using UnityEngine;
using UnityEngine.UI;
using Newtonsoft.Json;
using StackExchange.Redis;
using TMPro;
using WebSocketSharp;
using System;
using Newtonsoft.Json.Linq;
using PimDeWitte.UnityMainThreadDispatcher;

public class IdiomGame : MonoBehaviour
{
    public TextMeshProUGUI currentIdiomText;
    public TextMeshProUGUI nextIdiomText;
    public TextMeshProUGUI idiomInfoText;
    public TextMeshProUGUI jsonNameText;

    private IConnectionMultiplexer redisConnection;
    private IDatabase redisDatabase;
    private WebSocket webSocket;
    private string currentIdiom;

    void Start()
    {
        redisConnection = ConnectionMultiplexer.Connect("192.168.2.100:6379");
        redisDatabase = redisConnection.GetDatabase();
        webSocket = new WebSocket("ws://192.168.43.1:8083/websocket");
        webSocket.OnMessage += (sender, e) => ReceiveNextIdiomFromWebSocket(sender, e);
        webSocket.Connect();
        StartGame();
    }

    void StartGame()
    {
        RedisValue randomIdiom = redisDatabase.SetRandomMember("idioms");
        currentIdiom = randomIdiom.HasValue ? randomIdiom.ToString() : null;

        if (!string.IsNullOrEmpty(currentIdiom))
        {
            UnityMainThreadDispatcher.Instance().Enqueue(() => DisplayCurrentIdiom(currentIdiom));
            PlayIdiomChain();
        }
        else
        {
            Debug.LogError("无法获取起始成语。");
        }
    }

    void PlayIdiomChain()
    {
        string nextIdiom = "下个成语";
        UnityMainThreadDispatcher.Instance().Enqueue(() => DisplayNextIdiom(nextIdiom));

        IdiomInfo idiomInfo = GetIdiomInfo(nextIdiom);
        if (idiomInfo != null)
        {
            UnityMainThreadDispatcher.Instance().Enqueue(() => DisplayIdiomInfo(idiomInfo, new WebSocketData()));
        }

        if (nextIdiom.Equals(currentIdiom, StringComparison.OrdinalIgnoreCase)) // 检测是否与当前成语相同
        {
            StartGame(); // 重新开始游戏
        }
        else
        {
            Invoke("WaitAndContinueIdiomChain", 30f);
        }
    }

    void WaitAndContinueIdiomChain()
    {
        currentIdiom = nextIdiomText.text.Replace("成语：", ""); // 获取当前成语
        UnityMainThreadDispatcher.Instance().Enqueue(() => DisplayCurrentIdiom(currentIdiom));
        PlayIdiomChain();
    }

    void ReceiveNextIdiomFromWebSocket(object sender, MessageEventArgs e)
    {
        string message = e?.Data;
        var jsonData = JsonConvert.DeserializeObject<WebSocketData>(message);
        string nextIdiom = jsonData?.content;

        if (!string.IsNullOrEmpty(nextIdiom) && redisDatabase.KeyExists(nextIdiom))
        {
            UnityMainThreadDispatcher.Instance().Enqueue(() =>
            {
                if (IsIdiomChainValid(currentIdiom, nextIdiom))
                {
                    DisplayNextIdiom(nextIdiom);
                    IdiomInfo idiomInfo = GetIdiomInfo(nextIdiom);
                    if (idiomInfo != null)
                    {
                        DisplayIdiomInfo(idiomInfo, jsonData);
                    }
                }
                else
                {
                    Debug.LogError("接龙规则不符合，成语首尾不匹配。");
                }
            });
        }
        else
        {
            Debug.LogError($"Redis 中不存在成语 {nextIdiom}。");
        }
    }

    bool IsIdiomChainValid(string currentIdiom, string nextIdiom)
    {
        return !string.IsNullOrEmpty(currentIdiom) && !string.IsNullOrEmpty(nextIdiom) &&
               currentIdiom[currentIdiom.Length - 1] == nextIdiom[0];
    }

    IdiomInfo GetIdiomInfo(string idiom)
    {
        string idiomInfoJson = redisDatabase.StringGet(idiom);

        if (string.IsNullOrEmpty(idiomInfoJson))
        {
            Debug.LogError($"无法获取成语 {idiom} 的信息。");
            return null;
        }

        try
        {
            JObject jsonObject = JObject.Parse(idiomInfoJson);
            string descriptionValue = jsonObject["derivation"]?.ToString();
            IdiomInfo idiomInfo = new IdiomInfo
            {
                Description = descriptionValue
            };

            return idiomInfo;
        }
        catch (Exception e)
        {
            Debug.LogError($"解析成语信息时发生异常：{e.Message}");
            return null;
        }
    }

    void DisplayCurrentIdiom(string currentIdiom)
    {
        this.currentIdiom = currentIdiom;
        currentIdiomText.text = "成语：" + currentIdiom;
    }

    void DisplayNextIdiom(string nextIdiom)
    {
        nextIdiomText.text = "成语：" + nextIdiom;
    }

    void DisplayIdiomInfo(IdiomInfo idiomInfo, WebSocketData webSocketData)
    {
        idiomInfoText.text = "成语简介：" + idiomInfo.Description;

        if (!string.IsNullOrEmpty(webSocketData.nickName))
        {
            jsonNameText.text = "JSON 名字：" + webSocketData.nickName;
        }
        else
        {
            jsonNameText.text = "JSON 名字：" + idiomInfo.JsonName;
        }
    }

    void OnDestroy()
    {
        if (redisConnection != null)
        {
            redisConnection.Close();
        }

        if (webSocket != null && webSocket.IsAlive)
        {
            webSocket.Close();
        }
    }
}

[Serializable]
public class IdiomInfo
{
    public string Idiom;
    public string Description;
    public string JsonName;
}

[Serializable]
public class WebSocketData
{
    public string nickName;
    public string content;
}
